/* 
 * StikiWeb Wiki - a Wiki for Hierarchical Organizations
 * $Id: ViewAttachmentAction.java,v 1.5 2006/07/20 21:18:26 biglee Exp $
 * 
 * ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is the StikiWeb Wiki 
 *
 * The Initial Developer of the Original Code is Lee Haslup (biglee@haslups.com).
 * Portions created by the Initial Developer are Copyright (C) 2004
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** 
 */
package org.stikiweb.struts;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.stikiweb.contentMagnager.AttachmentManager;
import org.stikiweb.contentMagnager.Base62;
import org.stikiweb.contentMagnager.PermissionManager;

/**
 * @author Allen L (BigLee) Haslup
 *
 */
public class ViewAttachmentAction extends StikiAction {

	/* (non-Javadoc)
	 * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	public ActionForward execute(
		ActionMapping mapping,
		ActionForm form,
		HttpServletRequest req,
		HttpServletResponse resp)
		throws Exception {

		// make sure our state is set up and good to go.
		setup(req);
		
		// get the name parameter
		String name = req.getParameter("name");
		if (name == null || name.length() == 0) {
			return mapping.findForward("failure");
		}

		// see if it exists
		AttachmentManager am = AttachmentManager.solo();
		if (!am.attachmentExists(name)) {
			return mapping.findForward("failure");
		}

		// check the user's permission for the attachment and try 
		// logging in if that might help.
		if (PermissionManager
			.solo()
			.userPermLevelForPage(getUserName(req), name)
			< PermissionManager.READ) {
			if (this.isLoggedIn(req)) {
				return mapping.findForward("failure");
			} else {
				return goLoginFirst("viewAttachment", "", name, req);
			}
		}

		// find file extension
		int dot = name.lastIndexOf('.');
		String ext = "";
		if (dot > 0) {
			ext = name.substring(dot + 1, name.length());
		}
		
		// find file name
		int slash = name.lastIndexOf('/');
		String filename = name;
		if (slash >= 0) {
			filename = name.substring(slash + 1, name.length());
		}

		// set mime type
		String mimeType = am.mimeFromExt(ext);
		resp.setContentType(mimeType);
		resp.setHeader("Content-disposition","inline; filename=\""+filename+"\"");
		
		// open a stream on the attachment
		InputStream in = am.getAttachmentStream(name);

		// We're writing to the response writer
		PrintWriter pw = resp.getWriter();
		
		// if attachment is an HTML page, remember the base
		if(mimeType.equalsIgnoreCase("text/html")) {
			// 	baseString will contain name w/o the HTML page (it may include 
			// a zip file and, possibly, additional path within the zip file)
			int slashloc = name.lastIndexOf('/');
			String baseString = name;
			if(slashloc>=0) {
				baseString = Base62.encode(name.substring(0,slashloc));
			}
			// compute the correct URL for the BASE tag.
			String serverName = req.getServerName();
			int serverPort = req.getServerPort();
			String serverPortSt = ":"+serverPort;
			if(serverPort==80)serverPortSt="";
			String requestURI = req.getRequestURI();
			int sloc = requestURI.lastIndexOf("/");
			String uriPrefix = "";
			if(sloc>0) uriPrefix = requestURI.substring(0,sloc);
			String href = "http://"+serverName+serverPortSt+uriPrefix+"/href/"+baseString+"/x.htm";
			// if there is a </HEAD> in the first 5000 characters insert the
			// base tag before it.  Else put it before the beginning.
			StringBuffer sb = new StringBuffer();
			try {
				// read the first 5000 characters
				int c = in.read();
				int count = 0;
				while(count++<5000 & c >= 0) {
					sb.append((char)c);
					c = in.read();
				}
				// find /head in either case
				int endHeadLoc = sb.indexOf("</head>");
				if(endHeadLoc<0) endHeadLoc = sb.indexOf("</HEAD>");
				// if we found it insert base tag before it in the string
				if(endHeadLoc>=0) {
					sb.insert(endHeadLoc,"<BASE href='"+href+"'>\n");
				}
				// if no /head tag write base tag before we write the string
				else {
					pw.print("<BASE href='"+href+"'>\n");
				}
				// write the first 5000 characters (poss w/ base tag inserted.)
				pw.write(sb.toString());
				// write the rest of the file (if any)
				while (c >= 0) {
					pw.write(c);
					c = in.read();
				}				
			} catch (IOException e) {
				// TODO: what?
			}
		}
		else {
			try {
				int c = in.read();
				while (c >= 0) {
					pw.write(c);
					c = in.read();
				}
			} catch (IOException e) {
				// TODO: what?
			}
		}
		
		// close the file so windows won't lock it...
		in.close();

		// We're done.  No forward needed. 
		return null;
	}

}
